import { FC, MouseEvent } from 'react'
import { Spin } from 'antd'
import useGetComponentInfo from '../hooks/useGetComponentInfo'
import { getComponentConfByType } from '../../../components/question-components'

import styles from './EditCanvas.module.scss'
import type { ComponentInfo } from '../../../store/components-reducer/types'
import { useDispatch } from 'react-redux'
import { componentAction } from '../../../store/components-reducer'
import classNames from 'classnames'
import useBindCanvasKeyPress from '../hooks/useBindCanvasKeyPress'
import SortableContainer from '../../../components/drag-sortable/SortableContainer'
import SortableItem from '../../../components/drag-sortable/SortableItem'

interface EditCanvasProps {
  loading: boolean
}

function genComponent(componentInfo: ComponentInfo) {
  const { type, props } = componentInfo

  const componentConf = getComponentConfByType(type)
  if (componentConf == null) return null

  const { Component } = componentConf
  return <Component {...props} />
}

const EditCanvas: FC<EditCanvasProps> = props => {
  const { loading } = props
  useBindCanvasKeyPress()
  const { componentList, selectedId } = useGetComponentInfo()
  const dispatch = useDispatch()

  function handleClick(event: MouseEvent<HTMLDivElement>, id: string) {
    event.stopPropagation()
    dispatch(componentAction.changeSelectedId(id))
  }

  function handleDragEnd(oldIndex: number, newIndex: number) {
    dispatch(componentAction.moveComponent({ oldIndex, newIndex }))
  }

  if (loading)
    return (
      <div style={{ textAlign: 'center', marginTop: '24px' }}>
        <Spin />
      </div>
    )

  return (
    <SortableContainer items={componentList.map(c => ({ ...c, id: c.fe_id }))} onDragEnd={handleDragEnd}>
      <div className={styles.canvas}>
        {componentList
          .filter(component => !component.isHidden)
          .map(component => {
            const wrapperDefaultClassName = styles['component-wrapper']
            const selectedClassName = styles.selected
            const wrapperClassName = classNames({
              [wrapperDefaultClassName]: true,
              [selectedClassName]: component.fe_id === selectedId,
              [styles.locked]: component.isLocked,
            })

            return (
              <SortableItem key={component.fe_id} id={component.fe_id}>
                <div className={wrapperClassName} onClick={e => handleClick(e, component.fe_id)}>
                  <div className={styles.component}>{genComponent(component)}</div>
                </div>
              </SortableItem>
            )
          })}
      </div>
    </SortableContainer>
  )
}

export default EditCanvas
